// CoCo-HTTP-Requests - 在CoCo中可用的http请求库
//                      A HTTP Request Library in CoCo
// Copyright (C) 2025  VekarisWesion

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

const axios = require('axios');

const types = {
    type: "COCO_HTTP_REQUESTS_WIDGET",
    icon: "https://static.bcmcdn.com/coco/player/unstable/S12_wHxdee.image/svg+xml?hash=FthciHHc6DN45bCsJNR5rylXmQ7x",
    title: "HTTP-Requests",
    version: "beta 0.1.0",
    isInvisibleWidget: true,
    isGlobalWidget: true,
    docs: {
        url: "https://gitee.com/vekariswesion/coco-http-requests/wikis/Home",
    },
    properties: [
        {
            key: "isDebug",
            label: "调试模式是否开启",
            valueType: "boolean",
            defaultValue: false,
            editorType: "OptionSwitch",
        },
        {
            key: "timeout",
            label: "请求超时时间",
            valueType: "number",
            defaultValue: 1000,
            editorType: "InputNumber",
            unit: "ms",
        },
    ],
    methods: [
        // 构建
        // 构建请求信息
        {
            key: "init_messages",
            label: "初始化请求信息",
            params: [
                // 仅为声明
            ],
        },
        {
            key: "set_headers",
            label: "设置请求头",
            params: [
                {
                    key: "key",
                    label: "请求头键为",
                    valueType: "string",
                    defaultValue: "",
                },
                {
                    key: "value",
                    label: "请求头值为",
                    valueType: "string",
                    defaultValue: "",
                },
            ],
        },
        {
            key: "delete_headers",
            label: "删除请求头",
            params: [
                {
                    key: "key",
                    label: "请求头键为",
                    valueType: "string",
                    defaultValue: "",
                },
            ],
        },
        // 构建请求体
        {
            key: "set_body",
            label: "设置请求体",
            params: [
                {
                    key: "content_type",
                    label: "请求体类型为",
                    valueType: "string",
                    defaultValue: "text/plain",
                    dropdown: [
                        { label: "文本格式", value: "text/plain" },
                        { label: "json格式", value: "application/json" },
                        { label: "表单数据x-www-form-urlencoded", value: "application/x-www-form-urlencoded" },
                        { label: "表单数据form-data", value: "multipart/form-data" },
                    ],
                },
                {
                    key: "value",
                    label: "请求体值为",
                    valueType: "string",
                    defaultValue: "",
                },
            ],
        },
        // 主要请求方法
        {
            key: "request",
            label: "请求",
            params: [
                {
                    key: "method",
                    label: "请求方法",
                    valueType: "string",
                    defaultValue: "GET",
                    dropdown: [
                        { label: "GET", value: "GET" },
                        { label: "POST", value: "POST" },
                        { label: "PUT", value: "PUT" },
                        { label: "DELETE", value: "DELETE" },
                        { label: "PATCH", value: "PATCH" },
                        { label: "OPTIONS", value: "OPTIONS" },
                        { label: "HEAD", value: "HEAD" },
                    ],
                },
                {
                    key: "url",
                    label: "请求URL",
                    valueType: "string",
                    defaultValue: "https://www.example.com",
                },
            ],
        },
    ],
    events: [
        {
            key: "onResponse",
            label: "收到响应",
            params: [
                {
                    key: "response",
                    label: "响应体",
                    valueType: "string",
                },
                {
                    key: "status",
                    label: "响应状态码",
                    valueType: "number",
                },
                {
                    key: "headers",
                    label: "响应头",
                    valueType: "string",
                },
                {
                    key: "isError",
                    label: "是否错误",
                    valueType: "boolean",
                },
                {
                    key: "error_message",
                    label: "错误信息",
                    valueType: "string",
                },
                {
                    key: "doesResponseExist",
                    label: "响应内容是否存在",
                    valueType: "boolean",
                }
            ],
        },
    ],
};


class HTTPRequests extends InvisibleWidget {
    constructor(props) {
        super(props);
        // 构建属性初始化
        this.headers = { "Content-Type": "text/plain" };
        this.body = "";

        this.isDebug = props.isDebug;
        this.timeout = props.timeout;
    }

    console = {
        // 调试控制台日志，智能输出
        // 使用箭头函数来继承外部this
        log: (message) => {
            if (this.isDebug) {
                console.log(message);
            }
        },
        info: (message) => {
            if (this.isDebug) {
                console.info(message);
            }
        },
        warn: (message) => {
            if (this.isDebug) {
                console.warn(message);
            }
        },
        error: (message) => {
            if (this.isDebug) {
                console.error(message);
            }
        }
    };
    // ---- end ----

    /**
     * 主要请求方法
     * @param {string} method 请求方法
     * @param {string} url 请求URL
     */
    request(method, url) {
        // 输出调试信息
        this.console.log(">>>>>>>>Start of Function Call>>>>>>>>");
        this.console.log("Function Name: request");
        this.console.log("Parameters:");
        this.console.log(`  method: ${method}`);
        this.console.log(`  url: ${url}`);
        this.console.log("<<<<<<<<End of Function Call<<<<<<<");

        /**
         * 日志输出函数
         * @param {string} method 请求方法
         * @param {string} url 请求URL
         * @param {string} status 响应状态
         * @param {object} response 响应体
         * @param {string} error_message 错误信息
         */
        const logRequest = (method, url, status, response, error_message) => {
            this.console.log(">>>>>>>>Start of Response>>>>>>>>");
            if (status === "suc") {
                this.console.log(`Your request was successful.`);
            } else if (status === "fai") {
                this.console.error(`Your request was failed.`);
                this.console.error(`Error: ${error_message}`);
            }
            this.console.info(`Method: ${method}`);
            this.console.info(`URL: ${url}`);
            if (response) {
                this.console.info(`Status Code: ${response.status}`);
                this.console.info(`Response Headers: ${JSON.stringify(response.headers, undefined, 2)}`);
                this.console.info(`Response Body: ${JSON.stringify(response.data, undefined, 2)}`);
            } else {
                this.console.log("Because of some problems, the response is not available.");
                this.console.log("Problem like: CORS Error, the URL is not correct, DNS Error, etc.");
            }
            this.console.log("<<<<<<<<End of Response<<<<<<<");
        };

        axios({
            method: method,
            url: url,
            headers: this.headers,
            data: this.body,
            timeout: this.timeout,
        }).then((response) => {
            logRequest(method, url, "suc", response);
            this.emit("onResponse", response.data, response.status, response.headers, false, "", true);
        }).catch((error) => {
            const response = error.response;
            logRequest(method, url, "fai", response, error.message);
            if (response) {
                this.emit("onResponse", response.data, response.status, response.headers, true, error.message, true);
            } else {
                this.emit("onResponse", "", -1, "", true, error.message, false);
            }
        });
    }

    /**
     * 清理旧的请求信息
     */
    init_messages() {
        // 输出调试信息
        this.console.log(">>>>>>>>Start of Function Call>>>>>>>>");
        this.console.log("Function Name: clean_messages");
        this.console.log("Parameters: None");
        this.console.log("<<<<<<<<End of Function Call<<<<<<<");

        this.headers = { "Content-Type": "text/plain" };
        this.body = "";
    }

    /**
     * 设置请求头
     * @param {string} key 请求头键
     * @param {string} value 请求头值
     */
    set_headers(key, value) {
        // 输出调试信息
        this.console.log(">>>>>>>>Start of Function Call>>>>>>>>");
        this.console.log("Function Name: set_headers");
        this.console.log("Parameters:");
        this.console.log(`  key: ${key}`);
        this.console.log(`  value: ${value}`);
        this.console.log("<<<<<<<<End of Function Call<<<<<<<");
        
        this.headers[key] = value;
    }

    /**
     * 删除请求头
     * @param {string} key 请求头键
     */
    delete_headers(key) {
        // 输出调试信息
        this.console.log(">>>>>>>>Start of Function Call>>>>>>>>");
        this.console.log("Function Name: delete_headers");
        this.console.log("Parameters:");
        this.console.log(`  key: ${key}`);
        this.console.log("<<<<<<<<End of Function Call<<<<<<<");

        // 检查请求头是否存在
        if (this.headers[key]) {
            delete this.headers[key];
        } else {
            this.console.warn(`Warning: Header ${key} does not exist.`);
        }
    }

    /**
     * 设置请求体
     * @param {string} content_type 请求体类型
     * @param {string} value 请求体值
     */
    set_body(content_type, value) {
        // 输出调试信息
        this.console.log(">>>>>>>>Start of Function Call>>>>>>>>");
        this.console.log("Function Name: set_body");
        this.console.log("Parameters:");
        this.console.log(`  content_type: ${content_type}`);
        this.console.log(`  value: ${value}`);
        this.console.log("<<<<<<<<End of Function Call<<<<<<<");

        this.body = value;
        this.headers["Content-Type"] = content_type;
    }

    // 属性获取与修改
    isDebug() {
        return this.isDebug;
    }

    setDebug(is_debug) {
        this.isDebug = is_debug;
    }

}

exports.types = types;
exports.widget = HTTPRequests;
